package com.chengyu.core.util.douyin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chengyu.core.domain.form.DouyinNewAccessTokenForm;
import com.chengyu.core.domain.form.DouyinNewRefreshTokenForm;
import com.chengyu.core.model.UmsMemberThirdAccount;
import com.chengyu.core.service.member.impl.MemberThirdAccountServiceImpl;
import com.chengyu.core.util.JsonUtil;
import com.chengyu.core.util.RedisUtil;
import com.chengyu.core.util.SpringUtils;
import com.chengyu.core.util.netty.HttpClientUtil;
import com.chengyu.core.utils.MD5Util;
import com.chengyu.core.utils.StringUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class DouyinUtil {

    public static final String DY_ACCESS_TOKEN_KEY = "dy_access_token";
    public static final String DY_REFRESH_TOKEN_KEY = "dy_refresh_token";
    public static final String QRCODE_URL = "https://open.douyin.com/oauth/get_qrcode/";
    public static final String CHECK_QRCODE_URL = "https://open.douyin.com/oauth/check_qrcode/";
    public static final String ACCESS_TOKEN_URL = "https://open.douyin.com/oauth/access_token/";
    public static final String USERINFO_URL = "https://open.douyin.com/oauth/userinfo/";
    public static final String RENEW_REFRESH_TOKEN = "https://open.douyin.com/oauth/renew_refresh_token/";
    public static final String REFRESH_TOKEN = "https://open.douyin.com/oauth/refresh_token/";
    public static final String CLIENT_TOKEN = "https://open.douyin.com/oauth/client_token/";
    public static final String GET_TICKET = "https://open.douyin.com/open/getticket/";
    public static final String VIDEO_LIST = "https://open.douyin.com/api/douyin/v1/video/video_list/";
    public static final String VIDEO_DATA = "https://open.douyin.com/api/douyin/v1/video/video_data/";
    public static final String GET_IFRAME_BY_VIDEO = "https://open.douyin.com/api/douyin/v1/video/get_iframe_by_video/";
    public static Map getSignature(String clientKey,String clientSecret) {
        String grant_type = "client_credential";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("grant_type", grant_type);
        jsonObject.put("client_key", clientKey);
        jsonObject.put("client_secret", clientSecret);
        String data = jsonObject.toJSONString();
        String token = HttpClientUtil.httpPostRequest(DouyinUtil.CLIENT_TOKEN, data);
        JSONObject jsonObjectToken = JSON.parseObject(token);
        String tokenStr = jsonObjectToken.getJSONObject("data").getString("access_token");
        String ticket = HttpClientUtil.httpGetRequest(DouyinUtil.GET_TICKET + "?access_token=" + tokenStr);
        JSONObject jsonObjectTicket = JSONObject.parseObject(ticket);
        String ticketStr = jsonObjectTicket.getJSONObject("data").getString("ticket");
        String nonce_str = "Wm3WZYTPz0wzccnW";
        Long timestamp = System.currentTimeMillis();
        String str = "nonce_str=" + nonce_str + "&ticket=" + ticketStr + "&timestamp=" + timestamp;
        String signature = MD5Util.MD5Encode(str, "utf-8");
        Map map= new HashMap();
        map.put("signature",signature);
        map.put("clientKey",clientKey);
        map.put("timestamp",timestamp);
        map.put("nonceStr",nonce_str);
        return map;
    }



    public static DouyinNewRefreshTokenForm reNewRefreshToken(String refresh_token,String clientKey) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("client_key", clientKey);
        jsonObject.put("refresh_token", refresh_token);
        String data = jsonObject.toJSONString();
        String refreshTokenDataStr = HttpClientUtil.httpPostRequest(DouyinUtil.RENEW_REFRESH_TOKEN, data);
        JSONObject refreshTokenDateJson = JSONObject.parseObject(refreshTokenDataStr);
        Gson gson = new Gson();
        //驼峰转换
        Object caseResult = JsonUtil.convertUnderlineToCamelCase(refreshTokenDateJson.toJSONString());
        JSONObject refreshTokenDateJsonCase = (JSONObject) caseResult;
        DouyinNewRefreshTokenForm douyinNewRefreshForm = gson.fromJson(refreshTokenDateJsonCase.getJSONObject("data").toString(), DouyinNewRefreshTokenForm.class);
        return douyinNewRefreshForm;
    }


    public static String getAccessToken(String openId,String clientKey) {
        //先从redis去获取
        RedisUtil redisUtil = (RedisUtil) SpringUtils.getBean("redisUtil");
        MemberThirdAccountServiceImpl memberThirdAccountService = (MemberThirdAccountServiceImpl) SpringUtils.getBean("MemberThirdAccountServiceImpl");
        String access_token = (String) redisUtil.getRedisValue(DouyinUtil.DY_ACCESS_TOKEN_KEY + "_" + openId);
        if (StringUtils.isBlank(access_token)) {
            //如果缓存里面没有token，说明已经过期了就去刷新 那就用refresh去刷新
            String refresh_token = (String) redisUtil.getRedisValue(DouyinUtil.DY_REFRESH_TOKEN_KEY + "_" + openId);
            if (StringUtils.isBlank(refresh_token)) {
                //如果refresh_token没有，就去刷新refresh_token
                List<UmsMemberThirdAccount> umsMemberThirdAccounts = memberThirdAccountService.selectThirdAccountByOpenId(openId);
                refresh_token = umsMemberThirdAccounts.get(0).getRefreshToken();//原始refresh_token
                DouyinNewRefreshTokenForm douyinNewRefreshForm = reNewRefreshToken(refresh_token,clientKey);
                if (douyinNewRefreshForm.getErrorCode().equals("10020")){
                        return "10020";
                }
                refresh_token = douyinNewRefreshForm.getRefreshToken();
                Long expires_in = douyinNewRefreshForm.getExpiresIn();
                redisUtil.delete(DouyinUtil.DY_REFRESH_TOKEN_KEY + "_" + openId);
                redisUtil.setRedisValue(DouyinUtil.DY_REFRESH_TOKEN_KEY + "_" + openId, refresh_token, expires_in, TimeUnit.SECONDS);
                //同时修改这个账号的refresh_token
                memberThirdAccountService.updateRefreshTokenByOpenId(openId, refresh_token);
            }
            String grant_type = "refresh_token";
            String client_key = clientKey;
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("grant_type", grant_type);
            jsonObject.put("client_key", client_key);
            jsonObject.put("refresh_token", refresh_token);
            String data = jsonObject.toJSONString();
            String accessTokenDataStr = HttpClientUtil.httpPostRequest(DouyinUtil.REFRESH_TOKEN, data);

            JSONObject accessTokenDateJson = JSONObject.parseObject(accessTokenDataStr);
            Gson gson = new Gson();
            //驼峰转换
            Object caseResult = JsonUtil.convertUnderlineToCamelCase(accessTokenDateJson.toJSONString());
            JSONObject accessTokenDateJsonCase = (JSONObject) caseResult;
            DouyinNewAccessTokenForm douyinNewAccessTokenForm = gson.fromJson(accessTokenDateJsonCase.getJSONObject("data").toString(), DouyinNewAccessTokenForm.class);
            access_token = douyinNewAccessTokenForm.getAccessToken();
            Long expires_in = douyinNewAccessTokenForm.getExpiresIn();


            //同时修改缓存中的token，和数据库的token
            redisUtil.delete(DouyinUtil.DY_ACCESS_TOKEN_KEY + "_" + openId);
            redisUtil.setRedisValue(DouyinUtil.DY_ACCESS_TOKEN_KEY + "_" + openId, access_token, expires_in, TimeUnit.SECONDS);
            //同时修改这个账号的refresh_token
            memberThirdAccountService.updateAccessTokenByOpenId(openId, access_token);
        }
        return access_token;
    }


}
